#!/usr/bin/env ruby
# command-modules - Example BeEF RESTful API script
# Retrieves module details and pops an alert dialog on all hooked browsers
# Refer to the wiki for info: https://github.com/beefproject/beef/wiki/BeEF-RESTful-API
##
require 'rest-client'
require 'json'
require 'optparse'
require 'pp'
require './lib/string' # colored strings
require './lib/print'  # print wrappers
require './lib/beef_rest_api'

if ARGV.length == 0
  puts "#{$0}:"
  puts "|  Example BeEF RESTful API script"
  puts "|  Use --help for help"
  puts "|_ Use verbose mode (-v) and debug mode (-d) for more output"
  exit 1
end

# API config
proto = 'http'
host = '127.0.0.1'
port = '3000'
user = 'beef'
pass = 'beef'

# Command line options
@debug = false
@verbose = false
OptionParser.new do |opts|
  opts.on('-h', '--help', 'Shows this help screen') do
    puts opts
    exit 1
  end
  opts.on('--host HOST', "Set BeEF host (default: #{host})") do |h|
    host = h
  end
  opts.on('--port PORT', "Set BeEF port (default: #{port})") do |p|
    port = p
  end
  opts.on('--user', "Set BeEF username (default: #{user})") do |u|
    user = u
  end
  opts.on('--pass', "Set BeEF password (default: #{pass})") do |p|
    pass = p
  end
  opts.on('--ssl', 'Use HTTPS') do
    proto = 'https'
  end
  opts.on('-v', '--verbose', 'Enable verbose output') do
    @verbose = true
  end
  opts.on('-d', '--debug', 'Enable debug output') do
    @debug = true
  end
end.parse!

@api = BeefRestAPI.new proto, host, port, user, pass

# Retrieve the RESTful API token
print_status "Authenticating to: #{proto}://#{host}:#{port}"
@api.auth

# Retrieve BeEF version
@api.version

# Retrieve module categories
print_debug @api.categories

# Retrieve modules
modules = @api.modules.flatten
exit 1 if modules.empty?
print_debug modules

# Retrieve module details
modules.each do |m|
  next if m['id'].nil?
  print_status "Retrieving module details [id: #{m['id']}]"
  details = @api.module_details(m['id'])
  print_debug details
end

# Retrieve online hooked browser list
hooks = @api.online_browsers.flatten
exit 1 if hooks.empty?
print_debug hooks

# Execute alert dialog on all online browsers
mod_id = @api.get_module_id "Alert_dialog"
hooks.each do |hook|
  next if hook['id'].nil?
  print_status "Executing module [id: #{mod_id}, browser: #{hook['id']}]"
  result = @api.execute_module(hook['session'], mod_id, { "text" => "hello!" })
  print_debug result
end

